package edu.washington.ling.syntric.proc;

import java.io.IOException;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;

import edu.washington.ling.syntric.io.ExampleDoc;
import edu.washington.ling.syntric.io.ExampleDocReader;
import edu.washington.ling.syntric.io.ExampleDocWriter;
import edu.washington.ling.syntric.io.Example;
import edu.washington.ling.syntric.io.TreeReader;
import edu.washington.ling.syntric.io.TreeRepresentation;
import edu.washington.ling.syntric.struct.error.CollectingExceptionHandler;
import edu.washington.ling.syntric.struct.error.InvalidValueException;
import edu.washington.ling.syntric.struct.error.IrregularTreeException;
import edu.washington.ling.syntric.struct.error.PrintingExceptionHandler;
import edu.washington.ling.syntric.struct.error.UnreadableRepresentationException;
import edu.washington.ling.syntric.struct.tree.Tree;
import edu.washington.ling.syntric.util.TreeUtils;


public class CheckDSFormat {

	private static CheckFormatOptions opts = new CheckFormatOptions();
	private static PrintingExceptionHandler pHandler = new PrintingExceptionHandler();
	
	public static void checkDSFormat(Tree tree) throws IrregularTreeException {
		CollectingExceptionHandler cHandler = new CollectingExceptionHandler();
		try {
			TreeUtils.checkDSRoot(tree);
		} 
		catch (IrregularTreeException e) {
			cHandler.handle(e);
		}
		if (cHandler.hasMessages()) {
			throw new IrregularTreeException("Irregularities found:", cHandler.getMessages());
		}
	}
	
	private static void checkInputFile() {
		int numExamples = 0;
		int numTrees = 0;
		int numGood = 0;
		try {
			ExampleDocReader exfr = ExampleDocReader.newReader(opts.inputFilePath, "xml");
			ExampleDoc exf = exfr.read();
			ExampleDocWriter exfw = ExampleDocWriter.newWriter(opts.outputFilePath, "xml");
			TreeReader trr = TreeReader.newReader(opts.treeFormat);
			Example exr = null;
			while ((exr = exf.getNextExample()) != null) {
				numExamples++;
				if (exr.hasTreeRep("DS")) {
					TreeRepresentation tr = exr.getTreeRep("DS");
					numTrees++;
					try {
						Tree tree = trr.readTree(tr);
						checkDSFormat(tree);
						numGood++;
					}
					catch (UnreadableRepresentationException e) {
						String errStr = String.format("Could not read representation '%s'", exr.getID());
						pHandler.handle(e, errStr);
						tr.addMetaData("unreadable");
					}
					catch (IrregularTreeException e) {
						String errStr = String.format("Found irregularties in tree '%s'", exr.getID());
						pHandler.handle(e, errStr);
						tr.addMetaData("irregular");
					}
				}
				exfw.writeExample(exr);
			}
			exfw.close();
		}
		catch (IOException e) {
			pHandler.handle(e, "DS format check failed", System.out);
			e.printStackTrace(System.out);
			System.exit(-1);
		}
		catch (InvalidValueException e) {
			pHandler.handle(e, "DS format check failed.", System.out);
			System.exit(-1);
		}
		System.out.println("DS format check was successful.");
		System.out.println(String.format("%d/%d trees were correctly formatted", numGood, numTrees));
		System.out.println(String.format("Processed %d total examples", numExamples));
	}
	
	public static void main(String[] args) {
		CmdLineParser parser = new CmdLineParser(opts);
		try {
			parser.parseArgument(args);
			checkInputFile();
		}
		catch(CmdLineException e) {
			System.out.println(e.getMessage());
			System.out.print("Usage: CheckDSFormat");
			parser.printSingleLineUsage(System.out);
			System.out.println();
			parser.printUsage(System.out);
			System.exit(-1);
		}
	}
}
